package hasthi.tools.analyze;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.text.DecimalFormat;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;

public class AnalyzeUtils {
    private static DecimalFormat df = new DecimalFormat(".0");
    public static String format(String str){
//        if(str.length() <17){
//            StringBuffer buf = new StringBuffer(str);
//            int padSize = 17 -str.length();
//            for(int i = 0;i<padSize;i++){
//                buf.append(" ");
//            }
//            return buf.toString();
//        }
        //return "\t\t"+str;
        return str +"\t";
    }
    public static DescriptiveStatistics removeOutliners(DescriptiveStatistics stats){
        double mean = stats.getMean();
        double stddev = stats.getStandardDeviation(); 
        
        DescriptiveStatistics newStat = DescriptiveStatistics.newInstance();
        double[] values = stats.getValues();
        for(double value:values){
            if(value > mean - 3*stddev && value < mean + 3*stddev){
                newStat.addValue(value);    
            }
        }
        return newStat;
    }

    
    
    public static int[] findFreqDistribution(DescriptiveStatistics stats){
        int stepCount = 100;
        double step = (stats.getMax() - stats.getMin())/stepCount;
        int[] freq = new int[stepCount];
        
        double[] data = stats.getValues();
        for(double val:data){
            int index = (int)Math.floor((val -stats.getMin())/step);
            if(index == 100){
                index--;
            }
            freq[index]++;
        }
        return freq;
    }
    
    public static String formatOne(DescriptiveStatistics data){
        double mean = data.getMean();
        double max = data.getMax();
        double min = data.getMin();
        int size = data.getValues().length;
        double median = data.getPercentile(50);
        double cov = data.getStandardDeviation()/mean;
   
        StringBuffer buf = new StringBuffer();
        buf.append(df.format(mean)).append("\t").append(df.format(median)).append("\t")
        .append(df.format(cov)).append("\t").append(size).append("\t").append(df.format(min)).append("\t")
        .append(df.format(max)).append("\t").append(df.format(confidence95Interval(data)));
        buf.append("\n");
        return buf.toString();
    }
    public static String formatOneWithConfInterval(DescriptiveStatistics data){
        double mean = data.getMean();
        double max = data.getMax();
        double min = data.getMin();
        int size = data.getValues().length;
        double median = data.getPercentile(50);
        double cov = data.getStandardDeviation()/mean;
        double confInter95 = confidence95Interval(data);
        //String confInterval = df.format(mean-confInter95) + "-" + df.format(mean+confInter95);
        String confInterval = df.format(confInter95);
        StringBuffer buf = new StringBuffer();
        buf.append(df.format(mean)).append("\t").append(df.format(median)).append("\t")
        .append(df.format(cov)).append("\t").append(size).append("\t").append(df.format(min)).append("\t")
        .append(df.format(max)).append("\t").append(confInterval);
        buf.append("\n");
        return buf.toString();
    }
    
    public static double confidence95Interval(DescriptiveStatistics data){
        double size = data.getValues().length;
        return 1.645*data.getStandardDeviation()/Math.sqrt(size);
    }
    
    public static double[][] transpose(double[][] values){
        if(values.length == 0){
            return new double[0][0];
        }
        
        int maxSize = 0;
        for(int i = 0;i<values.length;i++){
            if(values[i].length > maxSize){
                maxSize = values[i].length; 
            }
        }
        
        //System.out.println(maxSize);
        double[][] output = new double[maxSize][values.length];
        
        for(int i = 0;i<maxSize;i++){
            for(int j = 0;j<values.length;j++){
                if(values[j].length > i){
                    output[i][j] = values[j][i];    
                }
            }
        }
        return output;
    }
    
    public static String array2str(double[][] values,String header) throws IOException{
        FormattedTable table = new FormattedTable(header);
        for(int i = 0;i<values.length;i++){
            StringBuffer buf = new StringBuffer();
            for(int j = 0;j<values[0].length;j++){
                buf.append(String.valueOf(values[i][j]));
                buf.append("\t");
            }
           table.addLine(buf.toString());
        }
        return table.toString();
    }
    
    public static void write2File(double[][] values,Writer w) throws IOException{
        for(int i = 0;i<values.length;i++){
            for(int j = 0;j<values[0].length;j++){
                w.write(String.valueOf(values[i][j]));
                w.write("\t");
            }
            w.write("\n");
        }
    }
    
}
